﻿using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Sustainalytics.Claims;
using Sustainalytics.ESGRatings.BusinessLogic.ESGOnlineReport;
using Sustainalytics.ESGRatings.Service.Models;
using Sustainalytics.ESGRatings.Service.Models.Common;
using Sustainalytics.Utils;
using Sustainalytics.Auth.Claims;
using Sustainalytics.Utils.WebApi.ErrorCodes;
using System.Web.Http.Cors;
using MongoDB.Driver;
using Sustainalytics.Entities.ESGRatings;
using Sustainalytics.MongoDB.Extensions;

namespace Sustainalytics.ESGRatings.Service
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [ClaimsChecker("api/v1/company/esg")]
    [RoutePrefix("api/v1/company")]
    //[AutoInvalidateCacheOutput]
    [LogControllerFilter(true, true, false)]
    public class EsgThemeOverallPerformanceSummaryController : ApiController
    {
        private IOnlineResearchProductsBusinessLogicUnit _service;
        private IMongoCollection<EsgFocusThresholds> _esgFocusThresholdsCollection;

        public EsgThemeOverallPerformanceSummaryController()
        {
            Setup();
        }

        public EsgThemeOverallPerformanceSummaryController(IOnlineResearchProductsBusinessLogicUnit service,
            IMongoCollection<EsgFocusThresholds> esgFocusThresholdsCollection)
        {
            _service = service;
            _esgFocusThresholdsCollection = esgFocusThresholdsCollection;
        }

        // [CacheOutput(ServerTimeSpan = 100, ClientTimeSpan = 0, NoCache = true, MustRevalidate = true, Private = true)]
        [Route("{companyId}/esgThemeOverallPerformanceSummary")]
        [UniverseChecker("universeIds", AccountFeature.EsgRatingsOnlineReport)]
        public HttpResponseMessage Get(Guid companyId, [FromUri]Guid esgProfileId, [FromUri]EsgThemeEnum? theme = null, [FromUri]int[] universeIds = null)
        {
            try
            {
                if (esgProfileId == Guid.Empty) return Request.CreateResponse(HttpStatusCode.BadRequest,
                    new { ErrorStatusCode = WebAPIGeneralErrorCodes.InvalidEsgProfileId });

                var data = _service.GetThemePerformance(companyId, esgProfileId, theme.ToString(), universeIds);
                var result = data.ToDto();

                return Request.CreateResponse(HttpStatusCode.OK, result);
            }
            catch (ESGReasearchNotFoundException ex)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound, new
                {
                    errCode = ex.GetType().ToString(),
                    message = ex.Message
                });

            }
            catch (ESGReasearchNotInUniversesException ex)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound, new
                {
                    errCode = ex.GetType().ToString(),
                    message = ex.Message
                });

            }
            catch (Exception ex)
            {
                CommonEventSource.Log.Exception(ex);
                return Request.CreateResponse(HttpStatusCode.InternalServerError,
                    new { ErrorStatusCode = WebAPIGeneralErrorCodes.UnhandledException });
            }
        }

        [Route("esgThresholds/{peerGroup}/{theme}")]
        public HttpResponseMessage Get([FromUri]string peerGroup, [FromUri] ThresholdType theme = ThresholdType.Overall)
        {
            try
            {
                return Request.CreateResponse(HttpStatusCode.OK, _esgFocusThresholdsCollection
                .Aggregate()
                .Match(x => x.PeerGroup == peerGroup && x.Type == theme)
                .Project(x => new
                {
                    x.Value,
                    Lower = x.LowerBound,
                    Upper = x.UpperBound
                })
                .SortBy(x => x.Lower)
                .ToList());
            }
            catch (Exception ex)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound, new
                {
                    errCode = ex.GetType().ToString(),
                    message = ex.Message
                });

            }
        }

        private void Setup()
        {
            var cnxString = ClientDWConnection.GetConnectionString();

            _service = _service ?? new OnlineResearchProductsBusinessLogicUnit(cnxString);
            _esgFocusThresholdsCollection = MongoFactory.GetCollectionFromDatabase<EsgFocusThresholds>(cnxString);
        }
    }
}